#include "terrianGLSL.h"
#include "stdio.h"
#include "GL/glut.h"

//#include <GL/glaux.h>

#include <cmath>
#include <iostream>
#include <strstream>

using namespace std;

void drawCoordAxis()
{
	if(AppGloble::fuzuCallListNum != 0)
	{
		glCallList(AppGloble::fuzuCallListNum);
		return;
	}

	AppGloble::fuzuCallListNum = glGenLists(1);

	glNewList(AppGloble::fuzuCallListNum, GL_COMPILE);

	glColor3f(1.0f, 0.0, 0.0);//鲜红色，x正半轴
	glBegin(GL_LINES);
	glVertex3f(AppGloble::axlength,0.0,0.0);
	glVertex3f(0.0,0.0,0.0);   
	glEnd();
	//glFlush();

	//glColor3f(0.5, 0.0, 0.0);
	//glBegin(GL_LINES);
	//glVertex3f(-1.0,0.0,0.0);
	//glVertex3f(0.0,0.0,0.0);   
	//glEnd();

	glColor3f(0.0, 1.0f, 0.0);//绿色，y正半轴
	glBegin(GL_LINES);
	glVertex3f(0.0,AppGloble::axlength,0.0);
	glVertex3f(0.0,0.0,0.0);	
	glEnd();

	/*glColor3f(0.0, 0.0, 0.5);
	glBegin(GL_LINES);
	glVertex3f(0.0,-1.0,0.0);
	glVertex3f(0.0,0.0,0.0);
	glEnd();*/


	glColor3f(0.0, 0.0, 1.0f);//深蓝色，z正半轴
	glBegin(GL_LINES);
	glVertex3f(0.01, 0.01, AppGloble::axlength);
	glVertex3f(0.01, 0.01, 0.01);
	glEnd();

	glColor3f(1.0f, 0.0, 1.0f);
	glBegin(GL_POINTS);
	for(float longarg=0.0f; longarg<360.0f; longarg+=0.50f)
	{
		glVertex3f(3.0f*cos(longarg), 3.0f*sin(longarg), 0.0f);
	}
	glEnd();

	glColor3f(1.0f, 0.0f, 0.0f);
	glBegin(GL_POINTS);
	for(float latarg=0.0f; latarg<360.0f; latarg+=0.50f)
	{
		glVertex3f(0.0f, 3.0f*cos(latarg), 3.0f*sin(latarg));
	}
	glEnd();

	//glColor3f(0.0, 0.5, 0.0);
	//glBegin(GL_LINES);
	//glVertex3f(0.0, 0.0, -1.0);
	//glVertex3f(0.0, 0.0, 0.0);
	//glEnd();

	glEndList();	

}

void computFrameRate(int value)
{
	AppGloble::curFPS = AppGloble::frameRendered*2;
	AppGloble::frameRendered=0;	
	//为了每过500ms都调用该注册函数,需要这条语句,
	glutTimerFunc(500, computFrameRate, 0);
	//这条语句只是在会让computFrameRate函数在调用这条语句后执行一次
}


void showScenInf()
{
	glPushAttrib(GL_ENABLE_BIT);

	glDisable(GL_LIGHTING);
	glDisable(GL_BLEND);
	glDisable( GL_TEXTURE_2D );
	glDisable(GL_DEPTH_TEST);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(0.0, 800.0, 0.0, 600.0);

	glColor3f(1.0f,0.0f,1.0f);

	char fpsbuffer[]="       \0";

	sprintf(fpsbuffer,"%d",AppGloble::curFPS);

	glRasterPos3f(10.0f,540.0f,0.0f);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'F');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'P');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'S');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,':');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,' ');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,fpsbuffer[0]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,fpsbuffer[1]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,fpsbuffer[2]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,fpsbuffer[3]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,fpsbuffer[4]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,fpsbuffer[5]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'H');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'z');

	char eyex[18];
	sprintf(eyex,"%3.4f", AppGloble::noweye.eyex);

	glRasterPos3f(10.0,525.0f,0.0f);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'y');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'x');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,' ');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[0]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[1]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[2]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[3]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[4]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[5]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[6]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyex[7]);	


	char eyey[18];
	sprintf(eyey,"%3.4f", AppGloble::noweye.eyey);

	glRasterPos3f(10.0f,510.0f,0.0f);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'y');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'y');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,' ');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[0]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[1]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[2]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[3]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[4]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[5]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[6]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyey[7]);

	char eyez[18];
	sprintf(eyez,"%3.4f", AppGloble::noweye.eyez);

	glRasterPos3f(10.0f,495.0f,0.0f);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'y');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'e');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'z');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,' ');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[0]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[1]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[2]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[3]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[4]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[5]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[6]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,eyez[7]);

	char triangles[18];
	sprintf(triangles,"%d", (int)AppGloble::totalTriCount);

	glRasterPos3f(10.0f,480.0f,0.0f);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'t');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'n');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'u');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,'m');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,' ');
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,triangles[0]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,triangles[1]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,triangles[2]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,triangles[3]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,triangles[4]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,triangles[5]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,triangles[6]);
	glutBitmapCharacter(GLUT_BITMAP_8_BY_13,triangles[7]);

	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopAttrib();
}

void eyeDrawSet()
{
	glMatrixMode(GL_MODELVIEW);

	glLoadIdentity();	

	gluLookAt(AppGloble::noweye.eyex+AppGloble::eyetox,	
			  AppGloble::noweye.eyey+AppGloble::eyetoy,
			  AppGloble::noweye.eyez,
			  AppGloble::eyetox,		
			  AppGloble::eyetoy,			
			  0.0,
			  0.0,						0.0,						1.0);

	if(AppGloble::usingGLSL20)
	{
		glUseProgram(AppGloble::prgrm);
		/*glUniform3f(AppGloble::eyeposloc, 
			AppGloble::noweye.eyex,
			AppGloble::noweye.eyey,
			AppGloble::noweye.eyez);*/
		glUniform3f(AppGloble::eyeposloc, 
					int(AppGloble::noweye.eyex*AppGloble::detailGridNum)/float(AppGloble::detailGridNum), 
					int(AppGloble::noweye.eyey*AppGloble::detailGridNum)/float(AppGloble::detailGridNum), 
					AppGloble::noweye.eyez);
	}
}

void changePolygonMode()
{
	if(AppGloble::drawFillMode)
	{
		glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
		AppGloble::drawFillMode = false;
	}
	else
	{
		glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
		AppGloble::drawFillMode = true;
	}
}

//键盘响应函数
void keyFunc(unsigned char key, int x, int y)
{
	switch(key)
	{
		//拉近
	case '+':	
		{
			AppGloble::noweye.radius *= 0.95f;
		}
		break;

		//拉远
	case '-':	
		{
			AppGloble::noweye.radius *= (1.0f/0.95f);
		}
		break;

		//经度增加	
	case '6':	
		{
			AppGloble::noweye.longitude += (AppGloble::PI/180.0f);
		}
		break;

		//经度减	
	case '4':	
		{
			AppGloble::noweye.longitude -= (AppGloble::PI/180.0f);
		}
		break;

		//纬度增加
	
	case '8':	
		{
			AppGloble::noweye.latitude += (AppGloble::PI/180.0f);
		}
		break;

		//纬度减
	
	case '2':	
		{
			AppGloble::noweye.latitude -= (AppGloble::PI/180.0f);
		}
		break;
	
	case '5':	
		{
			changePolygonMode();
		}
		break;
	
	case '*':	
		{
			AppGloble::noweye.defaultPos();
		}
		break;

	case 'Q':
	case 'q':	
		{
			AppGloble::maxHightValue *= 0.95f;
			glUseProgram(AppGloble::prgrm);
			glUniform1f(AppGloble::maxHightloc, AppGloble::maxHightValue);
		}
		break;

	case 'P':
	case 'p':	
		{
			AppGloble::maxHightValue *= (1.0f/0.95f);
			glUseProgram(AppGloble::prgrm);
			glUniform1f(AppGloble::maxHightloc, AppGloble::maxHightValue);
		}
		break;

	case 't':
	case 'T':	
		{
			AppGloble::isColorTexUse = AppGloble::isColorTexUse==0?1:0;
			glUseProgram(AppGloble::prgrm);
			glUniform1i(AppGloble::isColorTexUseloc, AppGloble::isColorTexUse);
		}
		break;

	case 'r':
	case 'R':	
		{
			AppGloble::crateValue = AppGloble::crateValue>0.021f? (AppGloble::crateValue-0.02f):AppGloble::crateValue;
			glUseProgram(AppGloble::prgrm);
			glUniform1f(AppGloble::crateLoc, AppGloble::crateValue);	
		}
		break;

	case 'y':
	case 'Y':	
		{
			AppGloble::crateValue = AppGloble::crateValue<0.979f? (AppGloble::crateValue+0.02f):AppGloble::crateValue;
			glUseProgram(AppGloble::prgrm);
			glUniform1f(AppGloble::crateLoc, AppGloble::crateValue);	
		}
		break;	

	case 'i':
	case 'I':	
		{
			AppGloble::sceneInfNeed = !AppGloble::sceneInfNeed;
		}
		break;

	case 'c':
	case 'C':	
		{
			AppGloble::coordAxixNeed = !AppGloble::coordAxixNeed;
		}
		break;

	case 'a':
	case 'A':	
		{
			AppGloble::eyetox -= 0.1f;
		}
		break;

	case 'd':
	case 'D':	
		{
			AppGloble::eyetox += 0.1f;
		}
		break;

	case 'w':
	case 'W':	
		{
			AppGloble::eyetoy += 0.1f;
		}
		break;

	case 's':
	case 'S':	
		{
			AppGloble::eyetoy -= 0.1f;
		}
		break;

	default:
		break;
	}

	AppGloble::noweye.computPosXYZ();

	eyeDrawSet();
}


//键盘响应函数
void keyFunc_mandelbort(unsigned char key, int x, int y)
{
	switch(key)
	{
		//拉近
	case '+':	
		{
			AppGloble::noweye.radius *= 0.95f;
		}
		break;

		//拉远
	case '-':	
		{
			AppGloble::noweye.radius *= (1.0f/0.95f);
		}
		break;

		//经度增加	
	case 'l':	
		{
			AppGloble::noweye.longitude += (AppGloble::PI/180.0f);
		}
		break;

		//经度减	
	case 'r':	
		{
			AppGloble::noweye.longitude -= (AppGloble::PI/180.0f);
		}
		break;

		//纬度增加
	
	case 'u':	
		{
			AppGloble::noweye.latitude += (AppGloble::PI/180.0f);
		}
		break;

		//纬度减
	
	case 'd':	
		{
			AppGloble::noweye.latitude -= (AppGloble::PI/180.0f);
		}
		break;
	
	case '5':	
		{
			changePolygonMode();
		}
		break;
	
	case '*':	
		{
			AppGloble::noweye.defaultPos();
		}
		break;

	case 'z':	
		{
			AppGloble::MST_zoom /= 1.025f;

			glUseProgram(AppGloble::prgrm);
			
			glUniform1f(AppGloble::MST_zoomLOC, AppGloble::MST_zoom);
		}
		break;
	case 'Z':	
		{
			AppGloble::MST_zoom *= 1.025f;

			glUseProgram(AppGloble::prgrm);
			
			glUniform1f(AppGloble::MST_zoomLOC, AppGloble::MST_zoom);

		}
		break;

	case 'x':	
		{
			AppGloble::MST_inix -=0.05f;

			glUseProgram(AppGloble::prgrm);
			
			glUniform1f(AppGloble::MST_inixLOC, AppGloble::MST_inix);

		}
		break;
	case 'X':	
		{
			AppGloble::MST_inix +=0.05f;

			glUseProgram(AppGloble::prgrm);
			
			glUniform1f(AppGloble::MST_inixLOC, AppGloble::MST_inix);

		}
		break;

	case 'y':
		{
			AppGloble::MST_iniy -=0.05f;

			glUseProgram(AppGloble::prgrm);
			
			glUniform1f(AppGloble::MST_iniyLOC, AppGloble::MST_iniy);

		}
		break;
	case 'Y':
		{
			AppGloble::MST_iniy +=0.05f;

			glUseProgram(AppGloble::prgrm);
			
			glUniform1f(AppGloble::MST_iniyLOC, AppGloble::MST_iniy);

		}
		break;
	case 'c':
		{
			AppGloble::MST_xcen -=0.05f;

			glUseProgram(AppGloble::prgrm);
			
			glUniform1f(AppGloble::MST_xcenLOC, AppGloble::MST_xcen);

		}
		break;
	case 'C':
		{
			AppGloble::MST_xcen +=0.05f;

			glUseProgram(AppGloble::prgrm);
			
			glUniform1f(AppGloble::MST_xcenLOC, AppGloble::MST_xcen);

		}
		break;

	case 'v':
		{
			AppGloble::MST_ycen -=0.05f;

			glUseProgram(AppGloble::prgrm);
			
			glUniform1f(AppGloble::MST_ycenLOC, AppGloble::MST_ycen);

		}
		break;
	case 'V':
		{
			AppGloble::MST_ycen +=0.05f;

			glUseProgram(AppGloble::prgrm);
			
			glUniform1f(AppGloble::MST_ycenLOC, AppGloble::MST_ycen);

		}
		break;

	case 'f':
		{
			AppGloble::MST_maxforNum -= 1.0f;

			glUseProgram(AppGloble::prgrm);
			
			glUniform1f(AppGloble::MST_maxforNumLOC, AppGloble::MST_maxforNum);

		}
		break;
	case 'F':
		{
			AppGloble::MST_maxforNum += 1.0f;

			glUseProgram(AppGloble::prgrm);
			
			glUniform1f(AppGloble::MST_maxforNumLOC, AppGloble::MST_maxforNum);

		}
		break;

	default:
		break;
	}

	AppGloble::noweye.computPosXYZ();

	eyeDrawSet();
}

//点击鼠标的响应


//点击鼠标的响应函数
void mouseFunc(int button, int state, int x, int y)
{
	switch(button)
	{
		case GLUT_LEFT_BUTTON:
		{
			if(state == GLUT_DOWN)
			{
				AppGloble::ldown=true;
				AppGloble::mdownXpos = x;
				AppGloble::mdownYpos = y;

				AppGloble::oldLong = AppGloble::noweye.longitude;
				AppGloble::oldLat = AppGloble::noweye.latitude;

			}
			if(state == GLUT_UP)
			{				
				AppGloble::ldown=false;
			}
		}
		break;

		case  GLUT_RIGHT_BUTTON:
		{
			if(state == GLUT_DOWN)
			{
				AppGloble::rdown=true;
				AppGloble::mdownXpos = x;
				AppGloble::mdownYpos = y;
				AppGloble::oldRadius = AppGloble::noweye.radius;			
			}
			if(state == GLUT_UP)
			{
				AppGloble::rdown=false;
			}
		}
		break;
		
		default:
		break;

	}
}

//移动鼠标的响应函数
void mouseMotionFunc(int x, int y)
{
	if(AppGloble::ldown)
	{
		AppGloble::noweye.longitude = AppGloble::oldLong + (x - AppGloble::mdownXpos)*(AppGloble::PI/360.0f);
		AppGloble::noweye.latitude = AppGloble::oldLat + (y - AppGloble::mdownYpos)*(AppGloble::PI/360.0f);
	}

	if(AppGloble::rdown)
	{
		float theViewPort[4];
		glGetFloatv(GL_VIEWPORT,theViewPort);
		float height = theViewPort[3];

		AppGloble::noweye.radius = AppGloble::oldRadius*(1.0f + (y-AppGloble::mdownYpos)/height);
	}

	AppGloble::noweye.computPosXYZ();

	eyeDrawSet();
}
